import os
import socket
import time

from deprecated import deprecated

from Exception import IpError

q = ...


class ServerNodeManage:

    @staticmethod
    def choose_by_group(groupname, groups):
        for i in groups:
            if i.get('group') == "public" or i.get('group') == groupname:
                yield i.get("socket")

    @staticmethod
    def choose_by_name(name, groups):
        for i in groups:
            if i.get("name") == name:
                yield i

    @staticmethod
    def connect(ip_port):
        tcp_soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        print(ip_port)
        tcp_soc.sendto(b"Hello,I am Your Master", ip_port)
        return tcp_soc

    @staticmethod
    def o_get_accept(onee, soc: socket.socket, using_method, timeout=None):
        """
        Oneesama 等待 Sister 报告
        !该方法具有阻塞态 请使用线程或者进程进行创建!
        :return:
        """
        join_socket_count = 0
        start = time.time()
        timeout_count = 0
        if timeout is not None:
            soc.settimeout(5)
            timeout_count = timeout
        while time.time() - start <= timeout_count or timeout is None:
            try:
                socket_cli, socket_info = soc.accept()
                client_ip, client_port = socket_info

                new_socketList = onee.SocketList
                for index, i in enumerate(onee.SocketList):
                    ip = i.get("ip")
                    port = i.get("port")
                    if ip is None or port is None:
                        raise IpError("节点IP\Port未设置")
                    elif ip == client_ip and client_port == port:
                        join_socket_count += 1
                        new_socketList[index]['socket'] = socket_cli
                        using_method(f"新的Sister加入Oneesama\r\n\tIP:{client_ip}\r\n\tPORT:{client_port}")

                onee.SocketList = new_socketList
            except socket.timeout as e:
                using_method("【Oneesama】等待5s无反应")

            # region 验证是否等待到了全部集群
            isnone = True
            for i in onee.SocketList:
                if i.get("socket") is None:
                    isnone = False
                    break

            if isnone:
                print(onee.SocketList)
                using_method(f"等待完毕全部服务器")
                return

            # endregion
        else:
            using_method("【Onnesama】等待超时！ Oneesama 继续操作")
            if join_socket_count < 1:
                using_method(f"【Onnesama 警告】 没有任何Sister加入Oneesama退出")
                os._exit(1)

    @deprecated
    def o_get_accept_history_2(onee, soc: socket.socket, using_method, timeout=None):
        """
        Oneesama 等待 Sister 报告
        !该方法具有阻塞态 请使用线程或者进程进行创建!
        该方法已被弃用
        :return:
        """
        start = time.time()
        count = 0
        while True:
            if onee.startAccept:
                soc.settimeout(1)
                try:
                    client_socket, client_addr_info = soc.accept()
                except socket.error as e:
                    if timeout is not None:
                        now = time.time()
                        if now - start > timeout:
                            using_method(f"【Oneesama】等待超时 继续操作")
                            if count <= 0:
                                using_method(f"【Oneesama】没有集群参与！ Oneesama 退出!")
                                import os
                                os._exit(229)

                            break
                    continue
                SocketList = []
                for i in onee.SocketList:
                    ip = i.get("ip")
                    if ip is None:
                        raise IpError("你这个IP有问题诶")
                    elif ip == client_addr_info[0]:
                        i["socket"] = client_socket
                        break
                    SocketList.append(i)
                    using_method(f"【Oneesama】 有Sister服务器加入 并开始等待数据与任务 ip:port{ip} ")
                    count += 1
                # onee.SocketList =
                is_full = True
                for i in onee.SocketList:
                    co = i.get("socket")
                    if co is None:
                        print(i)
                        is_full = False
                        break
                if is_full:
                    using_method(f"【Oneesama】 所有集群服务器开启并全部响应! 开始处理数据")
                    onee.startAccept = False
